package edu.fileAndIo;

import java.io.*;
import java.util.Scanner;

public class IODemo {

    public static void main(String[] args) throws IOException, ClassNotFoundException {
//        outputStream();
//        readFile();
        objectStream();
    }

    //输入流     读数据
    //输出流     写数据
    //字节流   获取用户在控制台输入的数据将其保存到file2.txt文件中
    static void outputStream(){
        Scanner scanner = new Scanner(System.in);
        String s = scanner.nextLine();
        File file = new File("./dir/file2.txt");
        FileOutputStream outputStream = null;
        try {
            //字节 文件  输出流
            outputStream = new FileOutputStream(file);
            outputStream.write(s.getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                outputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            scanner.close();
        }
    }
    //字节输入流   读取信息
    static void readFile() throws IOException {
        FileInputStream inputStream = new FileInputStream("./dir/file2.txt");
        byte[] buffer = new byte[8];
        //读数据   一次读8个字节
        // 返回值：读入缓冲区的总字节数，如果是-1，表示文件读取完毕
        int i = inputStream.read(buffer);
        //循环读取
        while (i != -1){
            System.out.println(new String(buffer,0,i));
            i = inputStream.read(buffer);
        }
        inputStream.close();

    }
    //利用字节输入 输出流  实现文件的复制

    //字节缓冲流   自带缓冲区，用于减少和外部文件的直接操作 提高效率
    static void copy() throws IOException {
        File sourceFile = new File("./dir/file2.txt");
        File targetFile = new File("./dir/file3.txt");
        FileInputStream inputStream = new FileInputStream(sourceFile);
        //自带缓冲区的字节输入流
        BufferedInputStream bis = new BufferedInputStream(inputStream);

        FileOutputStream outputStream = new FileOutputStream(targetFile,true);
        //缓冲字节输出流
        BufferedOutputStream bos = new BufferedOutputStream(outputStream);
        byte[] buffer = new byte[8];
        //读取数据
        int i = bis.read(buffer);
        while (i != -1) {
            //循环读取的同时往目标文件写入数据
            bos.write(buffer);
            i = bis.read(buffer);
        }
        //刷新缓冲输出流  避免出现数据在缓冲区不出来
        bos.flush();
        bis.close();
        bos.close();
    }


    //字符流   Reader  读  Writer  写
    static void copy2() throws IOException {
        File sourceFile = new File("./dir/file2.txt");
        File targetFile = new File("./dir/file3.txt");
        FileReader fileReader = new FileReader(sourceFile);
        //如果指定第二个参数append为true 代表每次写操作为追加写
        FileWriter fileWriter = new FileWriter(targetFile,true);
        char[] ch = new char[8];
        //字符输入流  读取 文件
        int i = fileReader.read(ch);
        while (i != -1){
            //字符输出流 将内容写到指定的目标文件中
            fileWriter.write(ch,0,i);
            i = fileReader.read(ch);
        }
        fileReader.close();
        fileWriter.close();
    }

    //字符缓冲流
    static void copy3() throws IOException {
        File sourceFile = new File("./dir/file2.txt");
        File targetFile = new File("./dir/file3.txt");
        FileReader fileReader = new FileReader(sourceFile);
        //将常规字符流包装成带缓冲的字符输入流
        BufferedReader br = new BufferedReader(fileReader);
        //如果指定第二个参数append为true 代表每次写操作为追加写
        FileWriter fileWriter = new FileWriter(targetFile,true);
        //将字符输出流包装成带缓冲的字符输出流
        BufferedWriter bw = new BufferedWriter(fileWriter);
        char[] ch = new char[8];
        //字符输入流  读取 文件
        int i = br.read(ch);
        while (i != -1){
            //字符输出流 将内容写到指定的目标文件中
            bw.write(ch,0,i);
            i = fileReader.read(ch);
        }
        //缓冲流 最后记得刷新
        bw.flush();
        fileReader.close();
        fileWriter.close();
    }

    //对象流   保存对象的   数据持久化
    static void objectStream() throws IOException, ClassNotFoundException {
        User user = new User("jack");
        File file = new File("./dir/object.txt");
        if (!file.exists()){
            file.createNewFile();
        }
        //将对象保存到文件中
        FileOutputStream outputStream = new FileOutputStream(file);
        //对象输出流
        ObjectOutputStream ops = new ObjectOutputStream(outputStream);
        //将对象写入到指定的文件中
        ops.writeObject(user);
        //读取文件，将文件内容转成对象
        FileInputStream inputStream = new FileInputStream(file);
        ObjectInputStream ois = new ObjectInputStream(inputStream);
        user = (User) ois.readObject();
        System.out.println(user);

    }

    //转换流  字节与字符 能不能转换
    static void transfer() throws IOException {
        File sourceFile = new File("./dir/file2.txt");
        File targetFile = new File("./dir/file3.txt");
        FileInputStream inputStream = new FileInputStream(sourceFile);
        //字节输入流   转成 字符流   指定字节流以及编码格式   解码
        InputStreamReader isr = new InputStreamReader(inputStream,"UTF-8");
        BufferedReader br = new BufferedReader(isr);
        String s = br.readLine();

        //输出转换流
        FileOutputStream outputStream = new FileOutputStream(targetFile);
        OutputStreamWriter osw = new OutputStreamWriter(outputStream,"UTF-8");
        BufferedWriter bw = new BufferedWriter(osw);
        bw.write(s);
    }

}
//Serializable ： 序列化接口
// 序列化功能： 将对象转成二进制文件    反序列化：将二进制文件转成对应类型的对象
class User implements Serializable{
    //序列化id
    static final long serialVersionUID = 42L;

    String name;
    User(String name){
        this.name = name;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                '}';
    }
}


/**
 * io流: read 读  write 写
 */
